/*           Copyright(c) 2005-2008 Dave Sexton            *
 *                   HtmlEditor Control                    *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using mshtml;
using System.Windows.Forms;
using DaveSexton.Controls.Native;

namespace DaveSexton.Controls
{
	public abstract class HtmlDesigner : MarshalByRefObject, Native.IHTMLEditDesigner
	{
		#region Public Properties
		public HtmlDocument Document
		{
			get
			{
				return document;
			}
			internal set
			{
				document = value;
			}
		}
		#endregion

		#region Private / Protected
		private HtmlDocument document;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="HtmlDesigner" /> class for derived classes.
		/// </summary>
		protected HtmlDesigner()
		{
		}
		#endregion

		#region Methods
		[System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.LinkDemand,
			Flags = System.Security.Permissions.SecurityPermissionFlag.Infrastructure)]
		public override object InitializeLifetimeService()
		{
			return null;
		}

		protected virtual void OnErrorCaught(Exception exception)
		{
			// do nothing (this method is for derived classes)
		}

		protected abstract bool TranslateAccelerator(int id, HtmlEvent htmlEvent);

		protected abstract bool PreHandleEvent(int id, HtmlEvent htmlEvent);

		protected abstract bool PostHandleEvent(int id, HtmlEvent htmlEvent);

		protected abstract void PostEditorEventNotify(int id, HtmlEvent htmlEvent);

		/// <summary>
		/// When implemented by a derived class, creates a new instance of an <see cref="HtmlDesigner"/>
		/// for the new <paramref name="document"/>.
		/// </summary>
		/// <remarks>
		/// This method is called in the event that the <see cref="HtmlEditor.Document"/> is reloaded, 
		/// in which case all <see cref="HtmlDesigner"/>s must be recreated and reregistered.  The
		/// <see cref="HtmlEditor"/> handles the reregistration by calling this method on each designer
		/// that is currently registered with the editor.
		/// <para>
		/// <see cref="HtmlDesigner"/> implementations should either create and return a clone of themselves
		/// or return <strong>null</strong>, which indicates that the designer should not be registered
		/// for the new <paramref name="document"/>.
		/// </para>
		/// </remarks>
		/// <param name="document"><see cref="IHTMLDocument2"/> interface that is the new document of the 
		/// <see cref="HtmlEditor"/> for which the designer was previously registered.</param>
		/// <returns>A new <see cref="HtmlDesigner" /> for the specified <paramref name="document"/> 
		/// or <strong>null</strong>.</returns>
		protected internal abstract HtmlDesigner CreateForNewDocument(object newDocument);
		#endregion

		#region IHTMLEditDesigner Members
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
		int Native.IHTMLEditDesigner.TranslateAccelerator(int inEvtDispId, IHTMLEventObj pIEventObj)
		{
			try
			{
				return (TranslateAccelerator(inEvtDispId, new HtmlEvent(document, pIEventObj))) ? Constants.S_OK : Constants.S_FALSE;
			}
			catch (Exception ex)
			// this method is called from unmanged code so all exceptions must be prevented here or they will be swallowed and 
			// cause unpredictable results (such as the arrow keys being disabled - which has happened before)
			{
				try
				{
					OnErrorCaught(ex);
				}
				catch (Exception ex2)
				{
					System.Diagnostics.Trace.WriteLine(ex2);
				}
			}

			return Constants.S_FALSE;
		}

		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
		int Native.IHTMLEditDesigner.PreHandleEvent(int inEvtDispId, IHTMLEventObj pIEventObj)
		{
			try
			{
				return (PreHandleEvent(inEvtDispId, new HtmlEvent(document, pIEventObj))) ? Constants.S_OK : Constants.S_FALSE;
			}
			catch (Exception ex)
			// this method is called from unmanged code so all exceptions must be prevented here or they will be swallowed and 
			// cause unpredictable results (such as the arrow keys being disabled - which has happened before)
			{
				try
				{
					OnErrorCaught(ex);
				}
				catch (Exception ex2)
				{
					System.Diagnostics.Trace.WriteLine(ex2);
				}
			}

			return Constants.S_FALSE;
		}

		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
		int Native.IHTMLEditDesigner.PostHandleEvent(int inEvtDispId, IHTMLEventObj pIEventObj)
		{
			try
			{
				return (PostHandleEvent(inEvtDispId, new HtmlEvent(document, pIEventObj))) ? Constants.S_OK : Constants.S_FALSE;
			}
			catch (Exception ex)
			// this method is called from unmanged code so all exceptions must be prevented here or they will be swallowed and 
			// cause unpredictable results (such as the arrow keys being disabled - which has happened before)
			{
				try
				{
					OnErrorCaught(ex);
				}
				catch (Exception ex2)
				{
					System.Diagnostics.Trace.WriteLine(ex2);
				}
			}

			return Constants.S_FALSE;
		}

		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
		int Native.IHTMLEditDesigner.PostEditorEventNotify(int inEvtDispId, IHTMLEventObj pIEventObj)
		{
			try
			{
				PostEditorEventNotify(inEvtDispId, new HtmlEvent(document, pIEventObj));
			}
			catch (Exception ex)
			// this method is called from unmanged code so all exceptions must be prevented here or they will be swallowed and 
			// cause unpredictable results (such as the arrow keys being disabled - which has happened before)
			{
				try
				{
					OnErrorCaught(ex);
				}
				catch (Exception ex2)
				{
					System.Diagnostics.Trace.WriteLine(ex2);
				}
			}

			return Constants.S_FALSE;
		}
		#endregion
	}
}
